async = require 'async'
cheerio = require 'cheerio'
fs = require 'fs'
got = require 'got'
path = require 'path'

commonHeaders = require './common-headers'

saveAlbum = module.exports = (cookie, dist, { userId, albumId, skipPassword }) ->
  headers = {
    'Cookie': cookie
    ...commonHeaders
  }
  albumUrl = "http://photo.renren.com/photo/#{userId}/album-#{albumId}"
  try
    resp = await got albumUrl, { headers }
  catch err
    throw new Error("fetching album-#{albumId} of #{err}")

  $ = cheerio.load resp.body

  # console.log $('.password-font1').length
  if $('.password-font1').length > 0
    if skipPassword then return else throw new Error("Album #{albumId} is protected with password.")

  albumName = $('.ablum-infor h1').text().trim()
  throw new Error("fetching album-#{albumId} as no album name is found.") unless albumName

  photoNumbers = parseInt $('.ablum-infor .num').text().match /\d+/
  albumPages = Math.ceil photoNumbers / 40

  dist = path.join dist, albumName
  unless fs.existsSync dist
    fs.mkdirSync dist
  
  for page in [0..albumPages]
    try
      resp = await got "#{albumUrl}/bypage/ajax?curPage=#{page}&pagenum=40", {
        headers
        json: on
      }
      throw new Error("fetching photo list #{page}") unless resp.body.photoList
    catch err
      throw new Error("fetching photo list: #{err}")

    resp.body.photoList.forEach (photo) ->
      photoUrl = photo.xLarge
      unless photoUrl
        photoUrl = photo.largeUrl
        if not path.basename(photo.largeUrl).startsWith('p_')
          photoUrl = photo.largeUrl.replace 'large', 'original'
      savedPath = path.join dist, path.basename photoUrl

      return if fs.existsSync(savedPath) and fs.statSync(savedPath).size > 0
      
      if fs.existsSync(savedPath) and fs.statSync(savedPath).size == 0
        fs.unlinkSync savedPath
      
      tryTimes = 1
      while tryTimes < 3
        try
          await new Promise (resolve, reject) ->
            got
            .stream photoUrl
            .pipe fs.createWriteStream savedPath
            .on 'error', (err) ->
              console.error 'cat'
              reject err
            .on 'response', (resp) -> resolve resp
          break
        catch err
          await new Promise (resolve) -> setTimeout resolve, 1000

      console.error "fail to fetch #{photoUrl}"

unless module.parent
  do ->
    [_, _, userId, albumId] = require('process').argv
    if not userId or not albumId
      return console.error 'no user or album is provided.'
    cookie = fs.readFileSync path.join __dirname, '..', 'config', 'cookie'
    try
      await saveAlbum cookie, "cache", { userId , albumId }
      console.log "Saved."
    catch err
      console.error "#{err}"
